<?php
namespace App\Http\Controllers\Api;

use App\Api\Helpers\SendMessage;
use App\Models\MMemberVerify;
use App\Models\MShopGood;
use App\Models\MShopOrders;
use App\Models\MUser;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use EasyWeChat\Factory;
use App\Services\OSS;

/**
 * 订单
 *
 */
class OrderController extends ApiController{
    use SendMessage;
    /**
     * 身份证验证
     *
     */
    public function card_discern(Request $request){
        $file = $request->file('file');
        //获取上传图片的临时地址 //"C:\Windows\php9F19.tmp
        $tmppath = $file->getRealPath();
        //生成文件名--图片名称
        $fileName = str_random(5) . $file->getFilename() . time().'.'.$file->getClientOriginalExtension();
        $pathName=date('Y/m/d').'/'.$fileName;//拼接上传的文件夹路径(按照日期格式1810/17/xxxx.jpg)
        //上传图片到阿里云OSS
        OSS::publicUpload(config('oss.BucketName'), $pathName, $tmppath, ['ContentType'=> $file->getClientMimeType()]);

        //获取上传图片的Url链接
        $img_url= OSS::getPublicObjectURL(config('oss.BucketName'), $pathName);

        $log = [
            '$img_url' => $img_url
        ];
        Log::info('上传图片链接', $log);

        if ( $request->img_type == "Z") {

            /*$result = $this->member_card($img_url, $request->oper_type, $request->img_type, $request->phone);
            if($result == -1){
                return $this->ReturnMessage(2010, '验证失败');
            }*/
            // 验证通过
//            if( $result['CUSTNAME'] == $request->user_name && $result['CUSTCERTNO'] == $request->card ) {
                $verify_info = MMemberVerify::where(['card'=> $request->card])->orderBy('id', 'desc')->first();
                if ( !$verify_info ) {
                    // 将返回数据插入验证数据库
                    $insert_data = [
                        "name" => $request->user_name, //$result['CUSTNAME'],
                        "sex"=> 1, //$result['GENDER'] == "1" ? 1 : 0,
                        "card"=> $request->card, //$result['CUSTCERTNO'],
                        "register" => '河南省原阳县师寨镇何庄278号',//$result['ADDRESS'],
                        "phone" => $request->phone,
                        "verify_car_z" => '', //serialize($result),
                        "transcode_z" =>  '',//$result['TRANSACTIONID'],
                        "img_z" =>  $img_url,
                        "busi"=> '',//$result['busi'],
                        "add_time" => time()
                    ];
                    $id = MMemberVerify::insertGetId($insert_data);
                } else {
                    // 该用户信息已验证过  更新数据库信息
                    $update_data = [
                        "busi" => '', //$result['busi'],
                        "transcode_z" =>  '',//$result['TRANSACTIONID'],
                    ];
                    $update_res = MMemberVerify::where(['id'=> $verify_info->id])->update($update_data);
                    if ( $update_res >= 0 ) {
                        $id = $verify_info->id;
                        $img_url = $verify_info->img_z;
                    } else {
                        return $this->ReturnMessage(2018, '验证失败');
                    }
                }

                if ( $id ) {
                    return $this->ReturnMessage(200, '验证成功',['id'=> $id, 'img'=> $img_url]);
                } else {
                    return $this->ReturnMessage(2017, '验证失败');
                }
//            } else {
//                return $this->ReturnMessage(2009, '验证失败');
//            }
        } elseif ($request->img_type == "F"){
            // 身份证反面验证  首先查询出用户的数据信息
            $verify_info = MMemberVerify::where(['card'=> $request->card])->orderBy('id', 'desc')->first();
            if ( !$verify_info ) {
                return $this->ReturnMessage(2011, '验证信息获取失败');
            }
            /*$result = $this->member_card($img_url, $request->oper_type, $request->img_type, $request->phone, $verify_info->busi);
            if($result == -1){
                return $this->ReturnMessage(2012, '验证失败');
            }*/
            // 验证通过
            $update_data = [
                "verify_car_f" => '',//serialize($result),
                "transcode_f" => '',//$result['TRANSACTIONID'],
                "img_f" => $img_url,
            ];

            $result = MMemberVerify::where(['id'=> $verify_info->id])->update($update_data);
            if ( $result >= 0 ) {
                return $this->ReturnMessage(200, '验证成功', ['id'=> $verify_info->id, 'img'=> $img_url]);
            } else {
                return $this->ReturnMessage(2013, '验证失败');
            }
        } else {
            $verify_info = MMemberVerify::where(['card'=> $request->card])->orderBy('id', 'desc')->first();
            if ( !$verify_info ) {
                return $this->ReturnMessage(2014, '验证信息获取失败');
            }
            /*$result = $this->member_image($img_url, $request->oper_type, $verify_info->name, $verify_info->card, $request->phone, $verify_info->busi);
            if($result == -1){
                return $this->ReturnMessage(2015, '验证失败');
            }*/

            // 验证通过
            $update_data = [
                "verify_person" => '', //serialize($result),
                "transcode_p" => '', //$result['TRANSACTIONID'],
                "picnamepath" => '', //$result['PICNAMERPATH'],
                "img_p" => $img_url,
            ];

            $result = MMemberVerify::where(['id'=> $verify_info->id])->update($update_data);
            if ( $result >= 0 ) {
                return $this->ReturnMessage(200, '验证成功', ['id'=> $verify_info->id, 'img'=> $img_url]);
            } else {
                return $this->ReturnMessage(2016, '验证失败');
            }
        }
    }

    /**
     * 生成订单
     *
     */
    public function create_order(Request $request){
        $vali_data = $this->validator_fields($request);
        if($vali_data['code'] != 200){
            return $this->ReturnMessage(403, $vali_data['msg']);
        }

        // 订单异常字段  订单异常原因
        $request->is_normal = 0;
        $request->cancel_reason = '';

        // 验证用户信息
        $user_info = $request->user;
        if ( !$user_info->id ) {
            return $this->ReturnMessage(403, '用户信息有误');
        }

        // 根据用户uid获取该用户的代理商id
        $all_pid = DB::table('user_relation')->where(['user_id'=> $user_info->id])->get();
        $pid_array = [];
        $agent_id = 0;
        if ( $all_pid ) {
            foreach ($all_pid as $key=> $value) {
                array_push($pid_array, $value->pid);
            }
        }
        if (!empty($pid_array)) {
            $info = MUser::where(['level'=> 1])->whereIn('id',$pid_array)->orderBy('id', 'desc')->first();
            if ( $info ) {
                $agent_id = $info->id;
            }
        }

        // 验证商品信息
        $goods_info = MShopGood::where(['id'=>$request->goods_id, 'is_sale'=> 'on'])->first();
        if (!$goods_info) {
            return $this->ReturnMessage(403, '商品参数有误');
        }

        if ($goods_info->price != $request->payment) {
            return $this->ReturnMessage(403, '请确认商品的购买金额');
        }

        // 验证用户验证信息
        $verify_info = MMemberVerify::where(['card'=>$request->card])->orderBy('id', 'desc')->first();
        if (!$verify_info) {
            return $this->ReturnMessage(403, '用户验证有误');
        }

        // 验证用户输入姓名和用户输入的身份证号是否正确
        if ($request->name != $verify_info->name) {
            return $this->ReturnMessage(403, '请确认输入的用户名是否正确');
        }

        // 根据身份证号判断用户年龄是否符合16-60周岁
        $age = $this->get_age_card($verify_info->card);
        if( $age < 16 || $age > 60 ){
            // 标记该订单为异常订单  异常原因  年龄不符合要求
            $request->is_normal = 1;
            $request->cancel_reason = '年龄不符合要求';
        }

        // 判断地址是否异常
        $address_is_normal = $this->address_is_normal($request);
        if( $address_is_normal ){
            // 该订单标记为异常订单 异常原因  收货地址异常
            $request->is_normal = 1;
            $request->cancel_reason = '重复收货地址';
        }

        // 判断后台添加地址是否异常
        $address_normal = $this->address_normal($goods_info, $request, $user_info->id);
        if( $address_normal ){
            // 该订单标记为异常订单 异常原因  收货地址异常
            $request->is_normal = 1;
            $request->cancel_reason = '异常地址';
        }


        // 验证下单次数
        if ( $user_info->id != 10 ) {
            $limit_result = $this->order_limit($request, $verify_info, $user_info->id);
            if (!$limit_result) {
                return $this->ReturnMessage(403, '下单次数受到限制');
            }
        }


        if ($request->card != $verify_info->card) {
            return $this->ReturnMessage(403, '请确认输入的身份证号是否正确');
        }

        $res = $this->create_order_data($request, $goods_info, $user_info, $verify_info, $agent_id);
        if($res['code'] == 200) {
            // 订单创建成功
            $return_data = [
                'order_sn'=> $res['order_sn'],
                'wx_res'  => $res['wx_res'],
            ];
            return $this->ReturnMessage(200, '订单创建成功', $return_data);
        } else {
            // 订单创建失败
            return $this->ReturnMessage(403, '获取支付链接失败');
        }
    }

    /**
     * 订单生成限制
     * @param array $request 接收到的参数
     * @param object $verify_info 验证信息
     * @param object $uid 用户uid
     *
     * @return float
     */
    public function order_limit($request, $verify_info, $uid){
        // 获取限制天数
        $set_days_info = DB::table('shop_setting')->where(['name'=> 'days'])->first();
        $limit_day = $set_days_info ? $set_days_info->value: 30;
        // 获取限制次数
        $set_times_info = DB::table('shop_setting')->where(['name'=> 'orders'])->first();
        $limit_times = $set_times_info ? $set_times_info->value: 2;

        $limit_time = $limit_day * 86400;

        $order_info = MShopOrders::whereIn('status',[1, 2, 3])
            ->where(function($query) use($request, $verify_info){
                $query->where('ad_phone','=',$request->tel)
                    ->orWhere('ad_card','=',$verify_info->card);
            })
            ->where('created_at', '>=',date('Y-m-d H:i:s', (time()-$limit_time)))
            ->get();

        if($order_info){
            if( $order_info->count() >= $limit_times ){
                return false;
            }
        }

        return true;
    }

    /**
     * 生成订单
     * @param object $request 接收到的参数
     * @param object $goods_info 商品信息
     * @param object $user_info 购买用户信息
     * @param object $verify_info 用户购买时的运营商验证信息
     * @param string $agent_id 代理商id
     *
     * @return array
     */
    public function create_order_data($request, $goods_info, $user_info, $verify_info, $agent_id){
        // 判断支付金额是否为0 判断订单是否异常
        $order_status = 0;
        if ( $request->payment == 0 ) {
            $order_status = $request->is_normal ? 3 : 1;
        }
        DB::beginTransaction();
        try {
            $insert_data = [
                'goods_id' => $goods_info->id,
                'prod_id' => $goods_info->prod,
                'uid' => $user_info->id,
                'order_sn' => $this->makeOrderSn($user_info->id),
                'ad_province' => $request->province,
                'phone' => $request->phone,
                'region' => $request->region,
                'ad_city' => $request->city,
                'ad_country' => $request->country,
                'ad_name' => $request->name,
                'ad_card' => $request->card,
                'ad_phone' => $request->tel,
                'ad_detail' => $request->address,
                'rmb_price' => $request->payment,
                'price' => $request->payment,
                'status' => $order_status,
                'is_normal' => $request->is_normal,
                'cancel_reason' => $request->cancel_reason,
                'agent' => $agent_id,
                "ad_card_img" => $verify_info->img_z,
                "ad_card_imgs" => $verify_info->img_f,
                "ad_image" => $verify_info->img_p,
                "transaction_id" => $verify_info->transcode_z.','.$verify_info->transcode_f.','.$verify_info->transcode_p,
                "picnamepath" => $verify_info->picnamepath,
                "type" => $request->type,
                'created_at'=> date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME'])
            ];

            $res = MShopOrders::insert($insert_data);
            if (!$res) {
                DB::rollBack();
                throw new \LogicException('订单创建失败', 200101);
            }
            // 订单创建成功  调用微信支付
            if ($goods_info->price == 0) {
                // 创建订单  预占号
                $order_info = MShopOrders::where(['order_sn'=> $insert_data['order_sn']])->first();
                if (!$order_info) {
                    DB::rollBack();
                    throw new \LogicException('订单信息获取失败', 200104);
                }
                if( $order_info->is_normal == 0 ){
                    $data = $this->make_phone_order($order_info);

                    //kang
                    systemCommissions($order_info->uid, $insert_data['order_sn']);
                    $wx_res = MShopOrders::where(['order_sn' => $insert_data['order_sn']])->update(['order_operator'=> '测试']);
                    /*if ( $data['code'] == 201 ) {
                        // 预占号失败
                        $wx_res = MShopOrders::where(['order_sn' => $insert_data['order_sn']])->update(['status'=> 3, 'is_normal'=> 1, 'cancel_reason'=> $data['msg']]);
                    } else {
                        // 预占号成功  更新订单数据
                        systemCommissions($order_info->uid, $insert_data['order_sn']);
                        $wx_res = MShopOrders::where(['order_sn' => $insert_data['order_sn']])->update(['order_operator'=> $data['order_id']]);
                    }*/
                } else {
                    $wx_res = true;
                }

                $this->buy_success($order_info);

            } else {
                $wx_res = $this->get_weixin_pay_url($user_info, $insert_data['price'], $insert_data['order_sn']);
            }

            if ($wx_res) {
                $wx_params = ( $goods_info->price == 0 ) ? "": $this->h5_pay_params($wx_res['prepay_id']);
                DB::commit();
                return ['code'=>200, 'order_sn'=> $insert_data['order_sn'], 'wx_res'=> $wx_params];
            } else {
                DB::rollBack();
                throw new \LogicException('支付链接获取失败', 200102);
            }
        } catch (\LogicException $e) {
            DB::rollBack();
            return ['code'=> $e->getCode(), 'msg'=> $e->getMessage()];
        }
    }

    /**
     * 获取h5支付所需的参数
     *
     */
    public function h5_pay_params($prepay_id){
        $wxconfig = config("wechat.payment.default");

        $params = [
            "appId" => $wxconfig['app_id'],
            "timeStamp" => (string)time(),
            "nonceStr" => "e61463f8efa94090b1f366cccfbbb444",
            "package" => "prepay_id=".$prepay_id,
            "signType" => 'MD5',
        ];

        //签名步骤一：按字典序排序参数
        ksort($params);
        $string = $this->to_url_params($params);
        //签名步骤二：在string后加入KEY
        $string = $string . "&key=" . $wxconfig['key'];
        //签名步骤三：MD5加密
        $string = md5($string);
        //签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        $params['paySign'] = $result; //签名

        return $params;
    }

    /**
     * 获取微信下单时的参数
     * @param array $user_info 用户信息
     * @param float $money 用户充值金额
     * @param string $orderid 充值订单号
     *
     * @return array
     *
     */
    private function get_weixin_pay_url($user_info, $money, $orderid)
    {
        $wxconfig = config("wechat.payment.default");

        $notify_url = 'http://' . $_SERVER['HTTP_HOST'] . '/api/notify_wx';
        $datas = array();
        $datas['appid'] = $wxconfig['app_id']; //公众账号ID
        $datas['attach'] = $user_info->account;
        $datas['openid'] = $user_info->watchid;
        $datas['body'] = 'openCard';
        $datas['mch_id'] = $wxconfig['mch_id']; //商户号
        $datas['nonce_str'] = '1add1a30ac87aa2db72f57a2375d8fec';
        $datas['notify_url'] = $notify_url;
        $datas['out_trade_no'] = $orderid;
        $datas['total_fee'] = $money * 100;
        $datas['trade_type'] = 'JSAPI';

        //签名步骤一：按字典序排序参数
        ksort($datas);
        $string = $this->to_url_params($datas);
        //签名步骤二：在string后加入KEY
        $string = $string . "&key=" . $wxconfig['key'];
        //签名步骤三：MD5加密
        $string = md5($string);
        //签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        $datas['sign'] = $result; //签名

        writeLogs($datas, '微信支付调用参数', 'pay'); // 写入日志记录
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        $xml = $this->to_xml($datas);
        $response = $this->post_xml_curl($xml, $url, 6);
        $data = $this->from_xml($response);
        writeLogs($data, '微信支付调用成功', 'pay'); // 写入日志记录
        if ($data['return_code'] == 'SUCCESS' && $data['result_code'] == 'SUCCESS') {
            $retturn_data['sign'] = $data['sign'];
            $retturn_data['prepay_id'] = $data['prepay_id'];
            // 将请求参数  成功时返回参数写入日志
            return $retturn_data;
        } else {
            writeLogs([], '微信支付调用失败', 'pay'); // 写入日志记录
            return false;
        }
    }

    /**
     * 生成订单字段验证
     *
     */
    public function validator_fields($request){
        // 参数校验
        $validator = Validator::make($request->all(),
            [
                'goods_id'   => 'required', // 套餐id
                'name'       => 'required', // 身份证姓名
                'card'       => 'required', // 身份证号
                'tel'        => 'required', // 联系电话
                'region'     => 'required', //  号码归属地
                'phone'      => 'required', //  开户手机号
                'city'       => 'required', //  收货区县
                'address'    => 'required', //  收货详细地址
                'payment'    => 'required', //  支付金额
            ],
            [
                'goods_id.required'    => 'id参数缺失',
                'name.required'        => 'name参数缺失',
                'card.required'        => 'card参数缺失',
                'tel.required'         => 'tel参数缺失',
                'region.required'      => 'region参数缺失',
                'phone.required'       => 'phone参数缺失',
                'city.required'        => 'city参数缺失',
                'address.required'     => 'address参数缺失',
                'payment.required'     => 'payment参数缺失',
            ]
        );

        if ($validator->fails()) {
            $msg = '';
            foreach ($validator->getMessageBag()->toArray() as $k=>$error){
                $msg = $error[0];break;
            }
            return ['code'=> 201, 'msg'=> $msg];
        }

        return ['code'=> 200, 'msg'=> 'success'];
    }

    /**
     * 格式化参数格式化成url参数
     * @param array $datas 参数
     *
     * @return string
     */
    private function to_url_params($datas)
    {
        $buff = "";
        foreach ($datas as $k => $v) {
            if ($k != "sign" && $v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     * 输出xml字符
     * @param array $datas 参数数组
     *
     * @return string
     **/
    private function to_xml($datas)
    {
        $xml = "<xml>";
        foreach ($datas as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }

    /**
     * 将xml转为array
     * @param string $xml
     *
     * @return string
     */
    private function from_xml($xml)
    {
        if (!$xml) {
            echo "xml数据异常！";
        }
        //将XML转为array  禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $data;
    }

    /**
     * 以post方式提交xml到对应的接口url
     *
     * @param string $xml 需要post的xml数据
     * @param string $url url
     * @param int $second url执行超时时间，默认30s
     *
     * @return array
     */
    private function post_xml_curl($xml, $url, $second = 30)
    {
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //严格校验
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, false);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //运行curl
        $data = curl_exec($ch);
        //返回结果
        curl_close($ch);
        return $data;
    }

    /**
     * 证件文字识别
     * @param string $img_url 图片路由
     * @param string $type 运营商类型
     * @param string $img_type 图片类型 Z身份证正面 F身份证反面
     * @param string $phone_num 开户手机号
     * @param string $busi 识别流水号 身份证正反面和人像对比需要统一流水号
     *
     * @return string
     */
    public function member_card($img_url, $type, $img_type, $phone_num, $busi=''){
        if ( !$type ) {
            return -1;
        }

        if ($type == 1) {
            // 移动证件文字识别
            $code = 'UIP_CARD_CONTRAS';
            $img_data = base64_encode(file_get_contents($img_url));
            $data = $this->cardDiscern($code, $img_data, $img_type, $phone_num, $busi);
        } elseif($type == 2) {
            // 联通证件文字识别
            $data['code'] = 201;
        } else {
            // 电信证件文字识别
            $data['code'] = 201;
        }

        $log = [
            'type' => $type . ' (1:移动证件, 2: 联通证件, 电信证件)',
            '$data' =>$data,
        ];
        Log::info('证件文字识别', $log);

        if ($data['code'] == 200) {
            $array = json_decode($data['data']['json'], true);
            $data_array = $array['SO_MEMBER_DEAL'][0];

            if ($data_array['VERIFYRESULT'] == 0) {
                $data_array['busi'] = $data['data']['busi'];
                // 验证通过
                return $data_array;
            }
        }

        return -1;
    }

    /**
     * 人像对比
     * @param string $img_url  图片地址
     * @param string $type  运营商类型
     * @param string $name  验证姓名
     * @param string $cardno  验证身份证号
     * @param string $phone_num  开户手机号
     * @param string $busi  证件识别和人像对比统一业务流水号
     *
     * @return string
     */
    public function member_image($img_url, $type, $name, $cardno, $phone_num, $busi){
        if ( !$type ) {
            return -1;
        }
        if ($type == 1) {
            // 移动人像对比接口
            $code_person = 'UIP_IMAGE_CONTRAS';
            $data_person = base64_encode(file_get_contents($img_url));
            $data = $this->personImgDiscern($code_person, $data_person, $phone_num, $busi, $name, $cardno);
        } elseif($type == 2) {
            // 联通人像对比接口
            $data['code'] = 201;
        } else {
            // 电信人像对比接口
            $data['code'] = 201;
        }
        if ($data['code'] == 200) {
            $result_data = $data['data']['SO_MEMBER_DEAL'][0];
            if ($result_data['VERIFYRESULT'] == 0) {
                return $result_data;die;
            }
        }
        return -1;
    }

    /**
     * 订单查询
     *
     */
    public function order_query(Request $request){
        $tel = $request->tel;
        $user = $request->user;
        $card = $request->card;

        if ( !$tel || !$user->id || !$card) {
            return $this->ReturnMessage(201, '参数有误');
        }
        if (strlen($card) != 6) {
            return $this->ReturnMessage(201, '身份证后6位输入有误');
        }
        $order_list = MShopOrders::where(['ad_phone'=> $tel, 'uid'=> $user->id])->select('id','goods_id','uid','order_sn','num','rmb_price','created_at','status','is_normal','cancel_reason','type')->get();
        if($order_list)
        {
            foreach ($order_list as $key =>$val)
            {
                $goods_info=MShopGood::where('id',$val['goods_id'])->first();
                $order_list[$key]['goods_name']=$goods_info->name;
            }
            $order_info = MShopOrders::where(['ad_phone'=> $tel, 'uid'=> $user->id])->orderBy('id', 'desc')->first();
            if ( $order_info ) {
                $card_order = substr($order_info->ad_card,-6);
                if ( $card != $card_order ) {
                    return $this->ReturnMessage(201, '身份证后6位输入有误');
                }
            }
        } else {
            $order_list = [];
        }


        return $this->ReturnMessage(200,'查询成功',['list'=> $order_list]);
    }

    /**
     * 获取协议接口
     *
     */
    public function get_agreement(Request $request){
        $info = DB::table("shop_setting")->where(['name'=> 'ruwang'])->first();
        if ( !$info ) {
            $info = "";
        }

        return $this->ReturnMessage(200,'查询成功',['info'=> $info->value]);
    }

    /**
     * 生成订单编号(年月日时分秒(10)+随机2位++会员ID%10003位)，该值会传给第三方支付接口
     * 长度 =10位 + 4位 + 4位  = 18位
     * 1000个会员同一微秒提订单，重复机率为1/100
     * @return string
     */
    public function makeOrderSn($memberId, $flag = 'O') {
        return  $flag .date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8) . sprintf('%03d',(int) $memberId % 1000);
    }

    /**
     * 购买成功发送消息
     *
     */
    public function buy_success($order_info){
        $template_id = 'RnWD8sDGTeH99RO_b4XYJC3gSreCBTgVV__zsAeien8';
        $user_info = DB::table('users')->where(['id'=> $order_info->uid])->first();
        $goods_info = DB::table('shop_goods')->where(['id'=> $order_info->goods_id])->first();
        $data = [
            'first'    => '恭喜购买成功',
            'keyword1' => $order_info->phone,
            'keyword2' => $goods_info? $goods_info->name : '移动套餐',
            'keyword3' => $order_info->price,
            'keyword4' => '购买成功',
            'remark' => '如有疑问，请联系客服',
        ];
        $this->sendTemplateMessage($user_info->watchid, $template_id, $data);
        return true;
    }

    /**
     * 根据身份证号判断用户年龄
     * @param string   $id  身份证号
     *
     * @return string
     */
    public function get_age_card($id){

        //过了这年的生日才算多了1周岁
        if(empty($id)) return '';
        $date=strtotime(substr($id,6,8));
        //获得出生年月日的时间戳
        $today=strtotime('today');
        //获得今日的时间戳
        $diff=floor(($today-$date)/86400/365);
        //得到两个日期相差的大体年数

        //strtotime加上这个年数后得到那日的时间戳后与今日的时间戳相比
        $age=strtotime(substr($id,6,8).' +'.$diff.'years')>$today?($diff+1):$diff;

        return $age;
    }

    /**
     * 收货地址是否正常
     * @param array $request 接收到的参数
     *
     * @return float
     */
    public function address_is_normal($request){
        // 查询该地址是否已正常下单
        $limit_time = 30*86400;
        $order_info = MShopOrders::whereIn('status',[1, 2, 3])
            ->where(['ad_city'=> $request->city])
            ->where(['ad_detail'=> $request->address])
            ->where('created_at', '>=',date('Y-m-d H:i:s', (time()-$limit_time)))
            ->get();

        if($order_info->count() > 0){
            return true;
        }

        return false;
    }

    /**
     * 收货地址是否正常
     * @param array $request 接收到的参数
     * @param object $goods_info 商品信息
     *
     * @return float
     */
    public function address_normal($goods_info, $request, $uid){
        // 查询该地址是否已正常下单
        if($goods_info->count() > 0){
            $address_arr = explode(';', $goods_info->unusual_info);
            if( count($address_arr) > 0 ) {
                foreach ($address_arr as $key=> $value) {
                    $return_float = false;
                    $admin_address = explode(',', $value);
                    $city_address = explode(',', $request->city);
                    $address_count = count($admin_address);
                    switch ($address_count) {
                        case 1;
                            if ( $admin_address[0] == mb_substr($city_address[0] , 0 , 2) ) {
                                $return_float = true;
                            }
                            break;
                        case 2:
                            if ( $admin_address[0] == mb_substr($city_address[0] , 0 , 2) ) {
                                if( $admin_address[1] == mb_substr($city_address[1] , 0 , 2) || $admin_address[1] == mb_substr($city_address[2] , 0 , 2) ){
                                    $return_float = true;
                                } else {
                                    $return_float = false;
                                }
                            }
                            break;
                        case 3:
                            if ( $admin_address[0] == mb_substr($city_address[0] , 0 , 2) &&
                                $admin_address[1] == mb_substr($city_address[1] , 0 , 2) &&
                                $admin_address[2] == mb_substr($city_address[2] , 0 , 2) ) {
                                $return_float = true;
                            }
                            break;
                        default:
                            $return_float = false;
                    }

                    if ($return_float) {
                        return true;
                        break;
                    }else{
                        continue;
                    }
                }
            }
        }

        return false;
    }
}
